<?php

namespace app\api\services;

use app\admin\model\Admin;
use app\admin\model\Order;
use app\admin\model\Technician;
use app\admin\model\User;
use app\admin\model\UserExtendMoneyLog;
use app\admin\model\UserMoneyLog;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
use think\facade\Log;
use Throwable;

class OrderFunc
{
    /**
     * 完成订单
     * @param $orderInfo
     * @return bool
     */
    public function completeService ($orderInfo): bool
    {
        $orderInfo->order_state = 'Completed'; //已完成
        $orderInfo->evaluate_state = 'ToBeEvaluated'; //待评价

        #查询技师最新的余额表更
        $technicianMoneyLog = Db::name('technician_money_log')->where('technician_id', $orderInfo->technician_id)->order('create_time', 'desc')->find();

        $technician = Technician::where('technician_id', $orderInfo->technician_id)->find();

        #服务返佣比例
        $serviceInfo = \app\admin\model\service\Service::where('service_id', $orderInfo->service_id)->field('service_id,distribution_rebate,clock_distribution_rebate')->find();
        $distribution_rebate = $serviceInfo->distribution_rebate;
        $clock_distribution_rebate = $serviceInfo->clock_distribution_rebate;
        $agentInfo = Admin::where('bind_city_id', $orderInfo->area_id)->where('parent_id', 0)->where('is_agent', 1)->field('id,commission,money,clock_commission')->find();
        Log::info('代理商信息' . json_encode($agentInfo));
        #开启事务
        Db::startTrans();
        try {
            if ($orderInfo->type == 2) {
                $technician_money = $this->handle($agentInfo->clock_commission, $clock_distribution_rebate, $orderInfo, $agentInfo);
            } else {
                #正常订单
                $technician_money = $this->handle($agentInfo->commission, $distribution_rebate, $orderInfo, $agentInfo);
                #给技师加服务单数
                #现有服务单数+服务总单数
                $technician->service_order_num = $technician->service_order_num + $orderInfo->service_num;
                $technician->save();
            }
            $afterMoney = $technicianMoneyLog['after'] ?? 0;
            #更新订单状态
            $orderInfo->save();


            $newAfterMoney = bcadd($afterMoney, $technician_money, 2);
            Db::name('technician_money_log')->insert([
                'technician_id' => $orderInfo->technician_id,
                'order_id'      => $orderInfo->id,
                'money'         => $technician_money,
                'before'        => $afterMoney,
                'after'         => $newAfterMoney,
                'memo'          => '订单：' . $orderInfo->order_sn . '状态：完结 金额：' . $technician_money . '元',
                'create_time'   => date("Y-m-d H:i:s", time()),
                'type'          => 1
            ]);
            #修改技师表余额
            $technician->money = bcadd($technician->money, $technician_money, 2);
            $technician->save();

            if ($orderInfo->fare_price > 0) {
                Db::name('technician_money_log')->insert([
                    'technician_id' => $orderInfo->technician_id,
                    'order_id'      => $orderInfo->id,
                    'money'         => $orderInfo->fare_price,
                    'before'        => $newAfterMoney,
                    'after'         => bcadd($newAfterMoney, $orderInfo->fare_price, 2),
                    'memo'          => '车费金额 ' . $orderInfo->fare_price . '元',
                    'create_time'   => date("Y-m-d H:i:s", time()),
                    'type'          => 2
                ]);
            }

            #修改技师表余额
            $technician->money = bcadd($technician->money, $orderInfo->fare_price, 2);
            $technician->save();

            #取消技师预约
            Db::name('order_reservation')->where('technician_id', $orderInfo->technician_id)->where('reservation_time', date("Y-m-d H:i", strtotime($orderInfo->service_start_time)))->delete();

            #记录订单状态
            setOrderStateLog($orderInfo->id, 'Completed');
            Db::commit();
        } catch (Throwable $e) {
            Db::rollback();
            Log::error('订单完成失败：user_id :' . $orderInfo->user_id . ' order_id ' . $orderInfo->id . 'errMsg' . $e->getMessage());
            return false;
        }
        return true;
    }

    /**
     * 处理
     * @param $agent_scale //代理商抽成
     * @param $platform_scale //平台抽成
     * @param $orderInfo
     * @param $agentInfo
     * @return mixed
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     * @throws Throwable
     */
    protected function handle ($platform_scale, $agent_scale, $orderInfo, $agentInfo): mixed
    {
        $order_service_total = bcsub($orderInfo->service_reality_price, $orderInfo->fare_price, 2);

        Log::info('代理商抽成比例' . $agent_scale);
        $agent_scale = bcdiv($agent_scale, "100", 2);
        #平台分成
        Log::info('平台抽成比例' . $platform_scale);
        $platform_scale = bcdiv($platform_scale, "100", 2);

        $platform_money = bcmul($order_service_total, $platform_scale, 2);

        $this->giveaway_log(1, 1, $orderInfo->order_sn, $platform_scale, $platform_money);

        #代理商分成
        $agent_money = bcmul($order_service_total, $agent_scale, 2);
        list($agent_money, $scale) = $this->userShareMoney($orderInfo, $agent_money);
        $this->giveaway_log(2, $agentInfo->id, $orderInfo->order_sn, $agent_scale, $agent_money);

        #代理商加余额
        $agent_money_log = Db::name('agent_money_log')->where('agent_id', $agentInfo->id)->order('create_time', 'desc')->find();
        $afterMoney = $agent_money_log['after'] ?? 0;
        Db::name('agent_money_log')->insert([
            'agent_id'    => $agentInfo->id,
            'order_id'    => $orderInfo->id,
            'money'       => $agent_money,
            'before'      => $afterMoney,
            'after'       => bcadd($afterMoney, $agent_money, 2),
            'memo'        => '订单：' . $orderInfo->order_sn . '状态：完结 金额：' . $agent_money . '元',
            'create_time' => date("Y-m-d H:i:s", time()),
            'type'        => 1
        ]);
        $agentInfo->money = bcadd($agentInfo->money, $agent_money, 2);
        $agentInfo->save();


        #扣除用户或者技师的分成
        $technician_scale = bcsub("1", bcadd($platform_scale, $agent_scale, 2), 2);
        #技师分成
        $technician_money = bcmul($order_service_total, $technician_scale, 2);
//        $technician_scale = bcadd($technician_scale, $scale, 2);
        $this->giveaway_log(3, $orderInfo->technician_id, $orderInfo->order_sn, $technician_scale, $technician_money);
        return $technician_money;
    }


    /**
     * 扣除用户或者技师的分成
     * @return array
     * @throws Throwable
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    protected function userShareMoney ($orderInfo, $technician_money): array
    {
        $order_service_total = bcsub($orderInfo->service_reality_price, $orderInfo->fare_price, 2);

        $scale = 0;
        #查看当前用户是否有上级
        $userLevel = Db::name('user_level')->where('user_id', $orderInfo->user_id)->find();
        if (!empty($userLevel)) {
            $parent_user_id = $userLevel['parent_user_id'];
            $type = $userLevel['type'];
            if ($type == 1) {
                #推广员分享
                $extend_scale = get_sys_config('extend_scale');//获取推广员分成比例
                Log::info('推广员分成比例' . $extend_scale);
                $scale = bcdiv($extend_scale, "100", 2);
                #推广员余额
                $extend_money = bcmul($order_service_total, $scale, 2);
                #技师余额
                $technician_money = bcsub($technician_money, $extend_money, 2);

                #给推广员余额
                $userExtendMoneyModel = new UserExtendMoneyLog();
                $moneyInfo = Db::name('user_extend_money_log')->where('user_id', $parent_user_id)->order('create_time', 'desc')->find();
                $userExtendMoneyModel->user_id = $parent_user_id;
                $userExtendMoneyModel->money = $extend_money;
                $userExtendMoneyModel->before = $moneyInfo['after'] ?? 0;
                $userExtendMoneyModel->after = bcadd($moneyInfo['after'] ?? 0, $extend_money, 2);
                $userExtendMoneyModel->memo = '邀请用户：下单奖励';
                $userExtendMoneyModel->create_time = date('Y-m-d H:i:s', time());
                $userExtendMoneyModel->type = 1;
                $userExtendMoneyModel->save();

                $userInfo = User::where('id', $parent_user_id)->find();
                $userInfo->extend_money = bcadd($userInfo->extend_money, $extend_money, 2);
                $userInfo->save();

                $this->giveaway_log(5, $parent_user_id, $orderInfo->order_sn, $scale, $extend_money);
            } else {
                #判断当前用户是否是首次下单
                $isFirst = Order::where('user_id', $orderInfo->user_id)->where('id', '<>', $orderInfo->id)
                    ->where('order_state', 'Completed')->find();
                if (!$isFirst) {
                    #普通用户分享
                    $normal_scale = get_sys_config('share_scale');//获取普通用户分成比例
                    Log::info('普通用户分成比例' . $normal_scale);
                    $scale = bcdiv($normal_scale, "100", 2);
                    #普通用户余额
                    $normal_money = bcmul($order_service_total, $scale, 2);
                    #技师余额
                    $technician_money = bcsub($technician_money, $normal_money, 2);
                    #给普通用户余额
                    $userMoneyModel = new UserMoneyLog();
                    $moneyInfo = Db::name('user_money_log')->where('user_id', $parent_user_id)->order('create_time', 'desc')->find();
                    $userMoneyModel->user_id = $parent_user_id;
                    $userMoneyModel->money = $normal_money;
                    $userMoneyModel->before = $moneyInfo['after'] ?? 0;
                    $userMoneyModel->after = bcadd($moneyInfo['after'] ?? 0, $normal_money, 2);
                    $userMoneyModel->memo = '邀请用户：首次下单奖励';
                    $userMoneyModel->create_time = date('Y-m-d H:i:s', time());
                    $userMoneyModel->type = 1;
                    $userMoneyModel->save();

                    $userInfo = User::where('id', $parent_user_id)->find();
                    $userInfo->money = bcadd($userInfo->money, $normal_money, 2);
                    $userInfo->save();

                    $this->giveaway_log(4, $parent_user_id, $orderInfo->order_sn, $scale, $normal_money);
                }
            }

        }
        return [$technician_money, $scale];
    }


    #记录各种角色的分佣
    protected function giveaway_log ($type, $login_id, $order_sn, $scale, $money): void
    {
        Db::name('giveaway_log')->insert([
            'type'        => $type,
            'login_id'    => $login_id,
            'order_sn'    => $order_sn,
            'scale'       => $scale,
            'money'       => $money,
            'create_time' => date('Y-m-d H:i:s', time())
        ]);
    }
}